L.Model = L.Class.extend({
	includes : L.Mixin.Events,

	initialize : function(context, config, coupling) {
		
		var self = this;
		this._subjectVersionId = context.subjectVersionId;
		this._activityId = context.activityId;
		this._userId = context.userId;
		
		var types = this._types = [ 'personal', 'question', 'answer', 'screen' ];
		var RLTable = this._RLTable = {};
		
		for ( var l = 0; l < types.length; ++l ) {
			var couplingOptions = {
					carriedId: this._subjectVersionId + "-" + this._activityId + "-roomlist-" + types[l],
					adapter: coupling.activityAdapter,
					enabled: coupling.enabled
			};
			
			if ( types[l] == "personal" ) {
				couplingOptions.carriedId = "user-" + this._userId + "-" + couplingOptions.carriedId; 
				couplingOptions.adapter = coupling.personalAdapter;
			}
			
			RLTable[types[l]] = new L.RoomList(types[l], couplingOptions);
			RLTable[types[l]].on('roomAction', this.fireRoomActionProxy, this);
		}

//		RLTable['personal'] = new L.RoomList(subjectVersionId + userId + 'personal', 'personal');
//		RLTable['groupal'] = new L.RoomList(subjectVersionId + groupId + 'groupal', 'groupal');
//		RLTable['question'] = new L.RoomList(subjectVersionId + 'question', 'question');
//		RLTable['answer'] = new L.RoomList(subjectVersionId + groupId + 'answer', 'answer');
//		RLTable['screen'] = new L.RoomList(subjectVersionId + 'screen', 'screen');

//		for (i = 0, n = types.length; i < n; i++) {
//			type = types[i];
//			RLTable[type].on('roomAction', this.fireRoomActionProxy, this);
//		}
		
		setTimeout(function() {
			self.fire('ready', null);
		}, config.TIME_TO_READY);
	},

	fireRoomActionProxy : function(params) {
		this.fire('roomAction', params);
	},
	
	findRoom: function(roomId) {
		var roomList = this._getContainerRoomListById(roomId);
		if ( roomList != null )
			return roomList.getRoom(roomId);
		return null;
	},

	_getContainerRoomListById : function(roomId, fName, echoOff) {
		var RLTable = this._RLTable;
		var types = this._types;
		for (var i = 0, n = types.length; i < n; i++) {
			type = types[i];
			if (RLTable[type].containsRoomId(roomId)) {
				return RLTable[type];
			}
		}
		
		if ( Skt.groupsManager != null ) {
			for (i = 0; i < Skt.groupsManager.getNoteGroups().length; ++i) {
				if ( Skt.groupsManager.getNoteGroups()[i].getRoomList().containsRoomId(roomId) )
					return Skt.groupsManager.getNoteGroups()[i].getRoomList();
			}
			
			for (i = 0; i < Skt.groupsManager.getWorkGroups().length; ++i) {
				if ( Skt.groupsManager.getWorkGroups()[i].getRoomList().containsRoomId(roomId) )
					return Skt.groupsManager.getWorkGroups()[i].getRoomList();
			}
		}
		
		if (!echoOff) {
			console.log("[WARNING] L.Model." + (fName ? fName : "") + " no encuentra roomId:" + roomId);
		}
		return null;
	},

	_validationType : function(type, fName) {
		if ($.inArray(type, this._types) == -1) {
			console.log("[WARNING] L.Model." + (fName ? fName : "") + " utiliza type invalido: " + type);
		}
	},

	addRoom : function(type, options /* options.roomId */) {
		var roomId = options && options.roomId ? options.roomId : uniqueId();
		if (this._getContainerRoomListById(roomId, "addRoom", "echoOff") != null)
			console.log("[WARNING] Model.addRoom Se agrego un room con id existente: " + roomId);
		this._validationType(type, "addRoom");
		
		if ( type == "groupal" && options && options.name )
			Skt.groupsManager.getGroup(options.name, options.type).getRoomList().addRoom(roomId, Skt.user.id, options);
		else
			this._RLTable[type].addRoom(roomId, Skt.user.id, options);
	},

	removeRoom : function(roomId) {
		this._getContainerRoomListById(roomId, "removeRoom")
				.removeRoom(roomId);
	},

	moveRoom : function(roomId, old_index, new_index) {
		this._getContainerRoomListById(roomId, "moveRoom").moveRoom(
				roomId, old_index, new_index);
	},

	copyRoom : function(roomId) {
		var room = this._getContainerRoomListById(roomId, "copyRoom").getRoom(roomId);
		var elements = [];
		room.eachObject(function(obj) {
			elements.push(L.Util.extend({}, obj));
		});
		this._copiedElements = elements;
		this._copiedBackground = room.getBackground();
	},

	pasteRoom : function(roomId) {
		if (!this._copiedElements) {
			console.log("[WARNING] L.Model.pasteRoom no encontro elementos copiados para pegar");
			return;
		}
		var room = this._getContainerRoomListById(roomId, "pasteRoom").getRoom(roomId);
		if ( room && room.getRoomModerator().canEdit(Skt.user.id) ) {
			var elements = this._copiedElements;
			for (var i = 0, n = elements.length; i < n; i++) {
				// asignar un nuevo id a elemento copiado
				uniqueId(elements[i], true);
				// room.addObject(elements[i]);
				room.addCommand('addObject', { object : elements[i] });
			}
			room.setBackground(this._copiedBackground);
		} else {
			alert("You don't have permission to edit that slide.");
		}
	},

//	changeGroupalRoomList : function(groupId) {
//		if (RLTable['groupal'])
//			RLTable['groupal'].off('roomAction',this.fireRoomActionProxy, this);
//		RLTable['groupal'] = new L.RoomList(this._subjectVersionId + groupId,'groupal');
//		RLTable['groupal'].on('roomAction', this.fireRoomActionProxy,this);
//	},

	eachRoom : function(fn, context) {
		var RLTable = this._RLTable;
		var types = this._types;
		for (i = 0, n = types.length; i < n; i++) {
			type = types[i];
			RLTable[type].eachRoom(fn, context);
		}
	},

	eachRoomOf : function(type, fn, context) {
		this._validationType(type, "eachRoomOf");
		this._RLTable[type].eachRoom(fn, context);
	},

	getRoomListOf : function(type) {
		this._validationType(type, "getRoomListOf");
		return this._RLTable[type];
	}

});
